import hljs from 'highlight.js';

// 支持的语言映射
const LANGUAGE_MAP = {
  'js': 'javascript',
  'jsx': 'javascript',
  'ts': 'typescript',
  'tsx': 'typescript',
  'py': 'python',
  'rb': 'ruby',
  'go': 'go',
  'rs': 'rust',
  'php': 'php',
  'cpp': 'cpp',
  'c++': 'cpp',
  'cxx': 'cpp',
  'cc': 'cpp',
  'c': 'c',
  'cs': 'csharp',
  'sh': 'bash',
  'bash': 'bash',
  'zsh': 'bash',
  'fish': 'bash',
  'ps1': 'powershell',
  'sql': 'sql',
  'html': 'xml',
  'htm': 'xml',
  'xml': 'xml',
  'css': 'css',
  'scss': 'scss',
  'sass': 'sass',
  'less': 'less',
  'json': 'json',
  'yaml': 'yaml',
  'yml': 'yaml',
  'toml': 'toml',
  'ini': 'ini',
  'dockerfile': 'dockerfile',
  'docker': 'dockerfile',
  'makefile': 'makefile',
  'make': 'makefile',
  'vim': 'vim',
  'lua': 'lua',
  'perl': 'perl',
  'r': 'r',
  'matlab': 'matlab',
  'swift': 'swift',
  'kotlin': 'kotlin',
  'scala': 'scala',
  'clojure': 'clojure',
  'haskell': 'haskell',
  'erlang': 'erlang',
  'elixir': 'elixir',
  'dart': 'dart',
  'groovy': 'groovy',
  'powershell': 'powershell',
  'batch': 'batch',
  'cmd': 'batch'
};

// 规范化语言名称
function normalizeLanguage(lang) {
  if (!lang) return 'plaintext';
  
  const normalized = lang.toLowerCase().trim();
  return LANGUAGE_MAP[normalized] || normalized;
}

// 检测代码语言
function detectLanguage(code, hintLanguage) {
  // 首先尝试使用提示的语言
  if (hintLanguage) {
    const normalizedHint = normalizeLanguage(hintLanguage);
    if (hljs.getLanguage(normalizedHint)) {
      return normalizedHint;
    }
  }
  
  // 基于代码内容的简单启发式检测
  const codeLines = code.trim().split('\n');
  const firstLine = codeLines[0] || '';
  const codeContent = code.toLowerCase();
  
  // JavaScript/TypeScript 检测
  if (codeContent.includes('function') || codeContent.includes('const ') || 
      codeContent.includes('let ') || codeContent.includes('var ') ||
      codeContent.includes('=>') || codeContent.includes('import ') ||
      codeContent.includes('export ')) {
    if (codeContent.includes('interface ') || codeContent.includes('type ') ||
        codeContent.includes(': string') || codeContent.includes(': number')) {
      return 'typescript';
    }
    return 'javascript';
  }
  
  // Python 检测
  if (codeContent.includes('def ') || codeContent.includes('import ') ||
      codeContent.includes('from ') || codeContent.includes('print(') ||
      firstLine.startsWith('#!') && firstLine.includes('python')) {
    return 'python';
  }
  
  // Java 检测
  if (codeContent.includes('public class') || codeContent.includes('public static void main') ||
      codeContent.includes('package ') || codeContent.includes('import java.')) {
    return 'java';
  }
  
  // CSS 检测
  if (codeContent.includes('{') && codeContent.includes('}') && 
      (codeContent.includes(':') || codeContent.includes('@media'))) {
    return 'css';
  }
  
  // HTML 检测
  if (codeContent.includes('<') && codeContent.includes('>') &&
      (codeContent.includes('<!doctype') || codeContent.includes('<html') ||
       codeContent.includes('<div') || codeContent.includes('<span'))) {
    return 'xml';
  }
  
  // JSON 检测
  if ((codeContent.startsWith('{') && codeContent.endsWith('}')) ||
      (codeContent.startsWith('[') && codeContent.endsWith(']'))) {
    try {
      JSON.parse(code);
      return 'json';
    } catch (e) {
      // 不是有效的 JSON
    }
  }
  
  // Shell 脚本检测
  if (firstLine.startsWith('#!') && (firstLine.includes('bash') || firstLine.includes('sh')) ||
      codeContent.includes('#!/bin/') || codeContent.includes('echo ') ||
      codeContent.includes('export ') || codeContent.includes('alias ')) {
    return 'bash';
  }
  
  // 使用 highlight.js 的自动检测作为后备
  try {
    const result = hljs.highlightAuto(code);
    if (result.language && result.relevance > 5) {
      return result.language;
    }
  } catch (e) {
    console.warn('自动语言检测失败:', e);
  }
  
  return 'plaintext';
}

function processCodeBlocks(htmlContent) {
  return htmlContent.replace(/<pre><code([^>]*)>([\s\S]*?)<\/code><\/pre>/g, function(match, attributes, codeContent) {
    // 解析类名获取语言信息
    var classMatch = attributes.match(/class="([^"]*)"/) || ['', ''];
    var className = classMatch[1];
    var languageMatch = className.match(/(?:language-|hljs-)(\w+)/);
    var hintLanguage = languageMatch ? languageMatch[1] : null;
    
    // 解码HTML实体
    var plainTextContent = codeContent
      .replace(/<[^>]*>/g, '')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&amp;/g, '&')
      .replace(/&quot;/g, '"')
      .replace(/&#39;/g, "'")
      .replace(/&#x27;/g, "'")
      .replace(/&nbsp;/g, ' ');
    
    // 检测和规范化语言
    var detectedLanguage = detectLanguage(plainTextContent, hintLanguage);
    var language = normalizeLanguage(detectedLanguage);
    
    // 进行语法高亮
    var highlightedCode;
    var actualLanguage = language;
    
    try {
      // 首先尝试使用检测到的语言
      if (hljs.getLanguage(language)) {
        var result = hljs.highlight(plainTextContent, { 
          language: language,
          ignoreIllegals: true 
        });
        highlightedCode = result.value;
        actualLanguage = language;
      } else {
        // 如果语言不支持，使用自动检测
        var autoResult = hljs.highlightAuto(plainTextContent, [
          'javascript', 'typescript', 'python', 'java', 'cpp', 'c', 'csharp',
          'php', 'ruby', 'go', 'rust', 'swift', 'kotlin', 'scala',
          'html', 'css', 'scss', 'json', 'xml', 'yaml', 'sql',
          'bash', 'powershell', 'dockerfile', 'makefile'
        ]);
        highlightedCode = autoResult.value;
        actualLanguage = autoResult.language || 'plaintext';
      }
    } catch (error) {
      console.error('代码高亮失败:', error);
      // 降级处理：使用纯文本
      try {
        highlightedCode = hljs.highlight(plainTextContent, { 
          language: 'plaintext',
          ignoreIllegals: true 
        }).value;
        actualLanguage = 'plaintext';
      } catch (fallbackError) {
        // 最后的降级：直接使用原始内容
        highlightedCode = plainTextContent
          .replace(/&/g, '&amp;')
          .replace(/</g, '&lt;')
          .replace(/>/g, '&gt;');
        actualLanguage = 'text';
      }
    }
    
    // 转义用于data属性的内容
    var escapedContent = plainTextContent
      .replace(/&/g, '&amp;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#39;');
    
    // 显示友好的语言名称
    var displayLanguage = getDisplayLanguage(actualLanguage);
    
    return '<div class="code-block-container">' +
      '<div class="code-header-controls">' +
        '<div class="code-language-label">' + displayLanguage + '</div>' +
        '<button class="code-copy-button" data-code="' + escapedContent + '">' +
          '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
            '<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>' +
            '<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>' +
          '</svg>' +
          '<span>Copy</span>' +
        '</button>' +
      '</div>' +
      '<pre><code class="hljs language-' + actualLanguage + '">' + highlightedCode + '</code></pre>' +
    '</div>';
  });
}

// 获取显示用的语言名称
function getDisplayLanguage(language) {
  const displayNames = {
    'javascript': 'JavaScript',
    'typescript': 'TypeScript',
    'python': 'Python',
    'java': 'Java',
    'cpp': 'C++',
    'c': 'C',
    'csharp': 'C#',
    'php': 'PHP',
    'ruby': 'Ruby',
    'go': 'Go',
    'rust': 'Rust',
    'swift': 'Swift',
    'kotlin': 'Kotlin',
    'scala': 'Scala',
    'xml': 'HTML',
    'css': 'CSS',
    'scss': 'SCSS',
    'sass': 'Sass',
    'less': 'Less',
    'json': 'JSON',
    'yaml': 'YAML',
    'sql': 'SQL',
    'bash': 'Bash',
    'powershell': 'PowerShell',
    'dockerfile': 'Dockerfile',
    'makefile': 'Makefile',
    'plaintext': 'Text',
    'text': 'Text'
  };
  
  return displayNames[language] || language.toUpperCase();
}

function initCopyHandlers() {
  document.removeEventListener('click', handleCopyClick);
  document.addEventListener('click', handleCopyClick);
}

function handleCopyClick(e) {
  var copyButton = e.target.closest('.code-copy-button');
  if (copyButton == null) return;
  
  e.preventDefault();
  e.stopPropagation();
  
  var codeContent = copyButton.getAttribute('data-code');
  if (codeContent == null || codeContent == '') {
    var container = copyButton.closest('.code-block-container');
    var codeElement = container != null ? container.querySelector('pre code') : null;
    if (codeElement != null) {
      codeContent = codeElement.textContent || codeElement.innerText || '';
    }
  } else {
    var tempDiv = document.createElement('div');
    tempDiv.innerHTML = codeContent;
    codeContent = tempDiv.textContent || tempDiv.innerText || '';
  }
  
  if (codeContent == null || codeContent == '') return;
  
  try {
    if (navigator.clipboard && window.isSecureContext) {
      navigator.clipboard.writeText(codeContent).then(function() {
        showCopySuccess(copyButton);
      }).catch(function(err) {
        console.error('复制失败:', err);
        fallbackCopyToClipboard(codeContent, copyButton);
      });
    } else {
      fallbackCopyToClipboard(codeContent, copyButton);
    }
  } catch (err) {
    console.error('复制失败:', err);
    fallbackCopyToClipboard(codeContent, copyButton);
  }
}

function showCopySuccess(button) {
  button.classList.add('copied');
  button.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
    '<polyline points="20,6 9,17 4,12"></polyline>' +
    '</svg>' +
    '<span>Copied</span>';
  
  setTimeout(function() {
    button.classList.remove('copied');
    button.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
      '<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>' +
      '<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>' +
      '</svg>' +
      '<span>Copy</span>';
  }, 2000);
}

function fallbackCopyToClipboard(text, button) {
  var textArea = document.createElement('textarea');
  textArea.value = text;
  textArea.style.position = 'fixed';
  textArea.style.left = '-999999px';
  textArea.style.top = '-999999px';
  textArea.style.opacity = '0';
  textArea.style.pointerEvents = 'none';
  
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();
  
  try {
    var successful = document.execCommand('copy');
    if (successful) {
      showCopySuccess(button);
    } else {
      console.error('execCommand copy failed');
    }
  } catch (err) {
    console.error('Fallback copy failed:', err);
  } finally {
    document.body.removeChild(textArea);
  }
}

export { processCodeBlocks, initCopyHandlers };
